package com.yyy.test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

/**
 * 贪吃蛇游戏的核心实现类
 * 继承自 JPanel 并实现 ActionListener 用于处理游戏循环
 */
public class SnakeGame extends JPanel implements ActionListener {
    // 游戏配置常量
    private static final int WIDTH = 600;          // 游戏区域宽度
    private static final int HEIGHT = 600;         // 游戏区域高度
    private static final int DOT_SIZE = 20;        // 蛇身每节的大小
    private static final int ALL_DOTS = 900;       // 最大蛇身长度
    private static final int DELAY = 140;          // 游戏刷新延迟（毫秒）

    // 蛇的位置数组
    private final int[] x = new int[ALL_DOTS];
    private final int[] y = new int[ALL_DOTS];

    // 游戏状态变量
    private int dots;                   // 当前蛇的长度
    private int apple_x;                // 食物的X坐标
    private int apple_y;                // 食物的Y坐标
    private int score = 0;              // 游戏分数

    // 移动方向标志
    private boolean leftDirection = false;
    private boolean rightDirection = true;
    private boolean upDirection = false;
    private boolean downDirection = false;
    private boolean inGame = true;      // 游戏是否进行中

    // 游戏组件
    private Timer timer;                // 游戏循环计时器
    private Image ball;                 // 蛇身图片
    private Image apple;                // 食物图片
    private Image head;                 // 蛇头图片

    // 界面样式
    private final Color backgroundColor = new Color(40, 44, 52);
    private final Color gridColor = new Color(58, 64, 74);
    private final Color scoreColor = new Color(152, 195, 121);
    private final boolean showGrid = true;

    // 添加暂停状态变量
    private boolean isPaused = false;

    /**
     * 构造函数：初始化游戏面板
     */
    public SnakeGame() {
        initBoard();
    }

    // 实现 ActionListener 接口的 actionPerformed 方法
    @Override
    public void actionPerformed(ActionEvent e) {
        if (inGame && !isPaused) {  // 添加暂停检查
            checkApple();
            checkCollision();
            move();
        }
        repaint();
    }

    // 初始化游戏面板
    private void initBoard() {
        addKeyListener(new TAdapter());
        setBackground(backgroundColor);
        setFocusable(true);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        loadImages();
        initGame();
    }

    /**
     * 加载游戏图片资源，如果加载失败则使用简单图形代替
     */
    private void loadImages() {
        try {
            // 尝试从资源文件加载图片
            ImageIcon iid = new ImageIcon(getClass().getResource("/dot.png"));
            ball = iid.getImage();

            ImageIcon iia = new ImageIcon(getClass().getResource("/apple.png"));
            apple = iia.getImage();

            ImageIcon iih = new ImageIcon(getClass().getResource("/head.png"));
            head = iih.getImage();

            System.out.println("成功加载图片资源");
        } catch (Exception e) {
            System.out.println("无法加载图片资源，使用默认图形: " + e.getMessage());
            // 使用简单图形代替
            ball = createDotImage(Color.GREEN);
            apple = createDotImage(Color.RED);
            head = createDotImage(Color.BLUE);
        }
    }

    /**
     * 创建简单的圆形图像
     */
    private Image createDotImage(Color color) {
        BufferedImage image = new BufferedImage(DOT_SIZE, DOT_SIZE, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(color);
        g2d.fillOval(2, 2, DOT_SIZE-4, DOT_SIZE-4);
        g2d.dispose();
        return image;
    }

    // 初始化游戏状态
    private void initGame() {
        dots = 3;  // 初始长度为3
        score = 0;  // 初始分数为0

        // 初始化蛇的位置（从屏幕中央开始）
        int startX = (WIDTH / 2) / DOT_SIZE * DOT_SIZE;  // 确保对齐网格
        int startY = (HEIGHT / 2) / DOT_SIZE * DOT_SIZE;

        // 初始化蛇的初始位置
        for (int z = 0; z < dots; z++) {
            x[z] = startX - (z * DOT_SIZE);  // 水平排列
            y[z] = startY;
        }

        // 初始化方向
        leftDirection = false;
        rightDirection = true;
        upDirection = false;
        downDirection = false;

        // 生成第一个食物
        locateApple();

        // 启动定时器
        timer = new Timer(DELAY, this);
        timer.start();
    }

    // 重写 JPanel 的 paintComponent 方法，绘制游戏画面
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        doDrawing(g);
    }

    // 绘制游戏画面
    private void doDrawing(Graphics g) {
        if (inGame) {
            g.drawImage(apple, apple_x, apple_y, this);

            for (int z = 0; z < dots; z++) {
                if (z == 0) {
                    g.drawImage(head, x[z], y[z], this);
                } else {
                    g.drawImage(ball, x[z], y[z], this);
                }
            }

            if (showGrid) {
                drawGrid(g);
            }

            Toolkit.getDefaultToolkit().sync();

            // 绘制分数
            g.setColor(scoreColor);
            g.setFont(new Font("Arial", Font.BOLD, 20));
            g.drawString("Score: " + score, 10, 20);

            // 如果游戏暂停，显示暂停提示
            if (isPaused) {
                drawPauseScreen(g);
            }
        } else {
            gameOver(g);
        }
    }

    // 绘制网格
    private void drawGrid(Graphics g) {
        g.setColor(gridColor);

        for (int i = 0; i < WIDTH / DOT_SIZE; i++) {
            g.drawLine(i * DOT_SIZE, 0, i * DOT_SIZE, HEIGHT);
            g.drawLine(0, i * DOT_SIZE, WIDTH, i * DOT_SIZE);
        }
    }

    // 移动蛇
    private void move() {
        // 先移动蛇身
        for (int z = dots - 1; z > 0; z--) {  // 修改这里，从 dots-1 开始
            x[z] = x[z - 1];
            y[z] = y[z - 1];
        }

        // 再移动蛇头
        if (leftDirection) {
            x[0] -= DOT_SIZE;
        }
        if (rightDirection) {
            x[0] += DOT_SIZE;
        }
        if (upDirection) {
            y[0] -= DOT_SIZE;
        }
        if (downDirection) {
            y[0] += DOT_SIZE;
        }

        // 添加穿墙效果（可选）
        if (x[0] >= WIDTH) {
            x[0] = 0;
        }
        if (x[0] < 0) {
            x[0] = WIDTH - DOT_SIZE;
        }
        if (y[0] >= HEIGHT) {
            y[0] = 0;
        }
        if (y[0] < 0) {
            y[0] = HEIGHT - DOT_SIZE;
        }
    }

    // 检查蛇是否吃到食物
    private void checkApple() {
        if ((x[0] == apple_x) && (y[0] == apple_y)) {
            dots++;  // 增加蛇的长度
            score += 10;  // 增加分数
            locateApple();  // 生成新的食物
        }
    }

    private static final int RAND_POS = 29;

    /**
     * 优化的食物生成逻辑
     */
    private void locateApple() {
        int maxX = (WIDTH - DOT_SIZE) / DOT_SIZE;  // 确保食物在边界内
        int maxY = (HEIGHT - DOT_SIZE) / DOT_SIZE;

        boolean validLocation;
        do {
            validLocation = true;
            apple_x = ((int) (Math.random() * maxX)) * DOT_SIZE;
            apple_y = ((int) (Math.random() * maxY)) * DOT_SIZE;

            // 检查是否与蛇身重叠
            for (int z = 0; z < dots; z++) {
                if (x[z] == apple_x && y[z] == apple_y) {
                    validLocation = false;
                    break;
                }
            }
        } while (!validLocation);
    }

    // 检查蛇是否撞到自己或墙壁
    private void checkCollision() {
        for (int z = dots; z > 0; z--) {
            if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
                inGame = false;
            }
        }

        if (y[0] >= HEIGHT) {
            inGame = false;
        }

        if (y[0] < 0) {
            inGame = false;
        }

        if (x[0] >= WIDTH) {
            inGame = false;
        }

        if (x[0] < 0) {
            inGame = false;
        }

        if (!inGame) {
            timer.stop();
        }
    }

    /**
     * 改进的游戏结束画面
     */
    private void gameOver(Graphics g) {
        // 绘制半透明背景
        g.setColor(new Color(0, 0, 0, 180));
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制游戏结束信息
        String gameOver = "Game Over";
        String scoreText = "Final Score: " + score;
        String restart = "Press SPACE to Restart";

        g.setColor(new Color(255, 99, 71));  // 鲜艳的红色
        Font largeFont = new Font("Arial", Font.BOLD, 40);
        g.setFont(largeFont);
        FontMetrics metrics = getFontMetrics(largeFont);
        g.drawString(gameOver, (WIDTH - metrics.stringWidth(gameOver)) / 2, HEIGHT / 2 - 50);

        g.setColor(new Color(152, 195, 121));  // 绿色
        Font mediumFont = new Font("Arial", Font.BOLD, 30);
        g.setFont(mediumFont);
        metrics = getFontMetrics(mediumFont);
        g.drawString(scoreText, (WIDTH - metrics.stringWidth(scoreText)) / 2, HEIGHT / 2);

        g.setColor(new Color(229, 192, 123));  // 金色
        Font smallFont = new Font("Arial", Font.PLAIN, 20);
        g.setFont(smallFont);
        metrics = getFontMetrics(smallFont);
        g.drawString(restart, (WIDTH - metrics.stringWidth(restart)) / 2, HEIGHT / 2 + 50);
    }

    /**
     * 改进的键盘事件处理
     */
    private class TAdapter extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();

            // 处理空格键
            if (key == KeyEvent.VK_SPACE) {
                if (!inGame) {
                    // 游戏结束状态，重新开始游戏
                    resetGame();
                } else {
                    // 游戏进行中，切换暂停状态
                    isPaused = !isPaused;
                    if (isPaused) {
                        timer.stop();
                    } else {
                        timer.start();
                    }
                }
                return;
            }

            // 游戏进行中且未暂停时才处理方向键
            if (inGame && !isPaused) {
                if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
                    leftDirection = true;
                    upDirection = false;
                    downDirection = false;
                }

                if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
                    rightDirection = true;
                    upDirection = false;
                    downDirection = false;
                }

                if ((key == KeyEvent.VK_UP) && (!downDirection)) {
                    upDirection = true;
                    rightDirection = false;
                    leftDirection = false;
                }

                if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
                    downDirection = true;
                    rightDirection = false;
                    leftDirection = false;
                }
            }
        }
    }

    /**
     * 重置游戏状态
     */
    private void resetGame() {
        // 重置暂停状态
        isPaused = false;

        // 重置蛇的位置和方向
        dots = 3;
        score = 0;
        leftDirection = false;
        rightDirection = true;
        upDirection = false;
        downDirection = false;
        inGame = true;

        // 初始化蛇的位置（从屏幕中央开始）
        int startX = WIDTH / 2;
        int startY = HEIGHT / 2;
        for (int z = 0; z < dots; z++) {
            x[z] = startX - z * DOT_SIZE;
            y[z] = startY;
        }

        // 生成第一个食物
        locateApple();

        // 重启定时器
        if (timer != null) {
            timer.stop();
        }
        timer = new Timer(DELAY, this);
        timer.start();
    }

    // 添加暂停画面绘制方法
    private void drawPauseScreen(Graphics g) {
        // 绘制半透明背景
        g.setColor(new Color(0, 0, 0, 120));
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制暂停提示
        String pauseText = "PAUSED";
        String continueText = "Press SPACE to Continue";

        // 绘制暂停标题
        g.setColor(new Color(255, 255, 255));
        Font largeFont = new Font("Arial", Font.BOLD, 40);
        g.setFont(largeFont);
        FontMetrics metrics = getFontMetrics(largeFont);
        g.drawString(pauseText, (WIDTH - metrics.stringWidth(pauseText)) / 2, HEIGHT / 2 - 30);

        // 绘制继续提示
        Font smallFont = new Font("Arial", Font.PLAIN, 20);
        g.setFont(smallFont);
        metrics = getFontMetrics(smallFont);
        g.drawString(continueText, (WIDTH - metrics.stringWidth(continueText)) / 2, HEIGHT / 2 + 20);
    }
}
